package com.garlic.face.jlf.utils;

import android.graphics.Bitmap;
import android.hardware.usb.UsbDevice;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.garlic.face.jlf.App;
import com.garlic.face.jlf.transaction.Means;
import com.garlic.face.jlf.transaction.balance.DesUtil;
import com.garlic.face.jlf.transaction.bean.SaleFlow;
import com.printsdk.cmd.PrintCmd;
import com.printsdk.usbsdk.UsbDriver;

import org.xutils.common.util.LogUtil;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

/**
 * Created by lyq on 2018/5/28.
 * 打印类
 */

public class PrintUtil {
    private static final String TAG = "adasd";

    // --------------------- 美松 lyq start ---------------------
    /**
     * 权限卡打印
     */
    /*
    public static void printAuthCode(UsbDevice usbDev, UsbDriver usbDriver, String code, String password){
        int iStatus = getPrinterStatus(usbDev, usbDriver);
        LogFileUtil.writeLog("MS打印机状态：" + iStatus);
                try {
                    String qrStr = code + "&" + password;
                    //usbDriver.write(PrintCmd.PrintString("二维码测试",0));
                    usbDriver.write(PrintCmd.PrintQrcode(qrStr, 5, 4, 1));
                    //usbDriver.write(PrintCmd.PrintString("一维码测试", 0));
                    //usbDriver.write(PrintCmd.Print1Dbar(2, 100, 1, 2, 10, qrStr));
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
                    String time = dateFormat.format(new Date());
                    usbDriver.write(PrintCmd.PrintString(time, 0));
            // 走纸换行、切纸、清理缓存
            setFeedCut(1, usbDev, usbDriver); // 0全切 1半切
        } catch (Exception e) {
            LogFileUtil.writeLog(e.getMessage());
        }
    }
    */

    /**
     * 权限卡打印
     */
    public static void printAuthCode(UsbDevice usbDev, UsbDriver usbDriver,String code, String password){
        int iStatus = getPrinterStatus(usbDev, usbDriver);
        LogFileUtil.writeLog("MS打印机状态：" + iStatus);
        try {
            String key = Means.secretKey;
            SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
            String qrStr = null;
            try {
                qrStr = "$" + DesUtil.encryptPassword( df.format(new Date()) + "&" + code + "-" + password, key);
            } catch (Exception e) {
                e.printStackTrace();
            }
            LogUtils.d("printAuthCode: " + qrStr, true);
//                        String str = null;
//                        try {
//                            str = DesUtil.decryptPassword(qrStr);
//                        } catch (Exception e) {
//                            e.printStackTrace();
//                        }
            //usbDriver.write(PrintCmd.PrintString("二维码测试",0));

            usbDriver.write(PrintCmd.SetClean());
            usbDriver.write(PrintCmd.SetAlignment(1));
            usbDriver.write(PrintCmd.SetSizetext(0,1));
//            usbDriver.write(PrintCmd.PrintString("权限卡:[" + code + "]", 1));
            usbDriver.write(PrintCmd.PrintFeedline(1));
            usbDriver.write(PrintCmd.SetAlignment(1));
            usbDriver.write(PrintCmd.PrintQrcode(qrStr, 18, 8, 1));
            //usbDriver.write(PrintCmd.PrintString("一维码测试", 0));
            //usbDriver.write(PrintCmd.Print1Dbar(2, 100, 1, 2, 10, qrStr));
            usbDriver.write(PrintCmd.PrintFeedline(1));
            usbDriver.write(PrintCmd.SetClean());
            usbDriver.write(PrintCmd.SetAlignment(1));
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
            String time = dateFormat.format(new Date());
            time += "(当日有效)";
            usbDriver.write(PrintCmd.PrintString(time, 0));
            // 走纸换行、切纸、清理缓存
            setFeedCut(1, usbDev, usbDriver); // 0全切 1半切
        } catch (Exception e) {
            LogUtils.e(e.getMessage());
        }
    }

    public static String printjlf(UsbDevice usbDev, UsbDriver usbDriver){
        int iStatus = getPrinterStatus(usbDev, usbDriver);
        LogUtils.d("MS打印机状态：" + iStatus, true);
//        if (checkStatus(iStatus) != 0)
//            return convertPrintStatus(iStatus);
        try {
            StringBuilder sb = new StringBuilder();

            LogUtils.d(JSON.toJSONString(Means.getInstance().getPrintBillHead()), true);

            ArrayList<String> printList = Means.getInstance().getPrintBillHead();
            for(int i=0;i<printList.size(); i++){
                sb.append(printList.get(i).replace("\"", "").replace("\\", "")).append("\n");
            }

            sb.append(" \n ");

            usbDriver.write(PrintCmd.SetClean());
            usbDriver.write(PrintCmd.SetAlignment(0));

            int iRet = -1;
            byte[] bRead1 = new byte[1];
            byte[] bWrite1 = PrintCmd.PrintString(sb.toString(), 0);
            if (usbDriver.read(bRead1, bWrite1, usbDev) > 0) {
                iRet = PrintCmd.CheckStatus1(bRead1[0]);
            }
            if ( bRead1[0]!=0){
                return "打印失败";
            }
            // 走纸换行、切纸、清理缓存
            byte[] bRead2 = new byte[1];
            byte[] bWrite2 =PrintCmd.PrintFeedline(10);
            if (usbDriver.read(bRead2, bWrite2, usbDev) > 0) {
                iRet = PrintCmd.CheckStatus1(bRead2[0]);
            }
            if (bRead2[0]!=0){
                return "打印失败!";
            }
            byte[] bRead3 = new byte[1];
            byte[] bWrite3 =PrintCmd.PrintCutpaper(1);
            if (usbDriver.read(bRead3, bWrite3, usbDev) > 0) {
                iRet = PrintCmd.CheckStatus1(bRead3[0]);
            }
            if (bRead3[0]!=0){
                return "打印失败!!";
            }
        } catch (Exception e) {
            LogUtils.e(e.getMessage());
            return "打印失败:"+e.getMessage();
        }
        return "";
    }

    private static String appendSpace(String in, int len) {
        try {
            byte[] in_byte = in.getBytes("GBK");
            int byte_length = in_byte.length;
            if (byte_length <= len) {
                //byte 字符长度小于配置的长度时...后面补空格.
                String out = in;
                for (int i = 0; i < len - byte_length; i++) {
                    out += " ";
                }
                return out;
            } else {
                //byte 字符长度大于配置的长度时.截断到 length 位
                String out = "";
                for (int i = 0; i < in.length(); i++) {
                    String sub = in.substring(i, i + 1);
                    String tmp = out;
                    tmp += sub;
                    int tmp_length = tmp.getBytes("GBK").length;
                    if (tmp_length <= len) {
                        out = tmp;
                        if (tmp_length == len) {
                            return out;
                        }
                    } else {
                        //补空格
                        for (int k = 0; k < tmp_length - len; k++) {
                            out += " ";
                        }
                        break;
                    }
                }
                return out;
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return in;
        }
    }

    /**
     * 小票打印
     *
     * @param usbDev
     * @param usbDriver
     */
//    public static void printMSNote(Resources resources, UsbDevice usbDev, UsbDriver usbDriver,
//                                   Bitmap bitmap) {
//        int iStatus = getPrinterStatus(usbDev, usbDriver);
//        LogFileUtil.writeLog("MS打印机状态：" + iStatus);
////        if (checkStatus(iStatus) != 0)
////            return;
//        try {
//            Store store = CommonUtil.getInstance().getStore();
//            printMSWD(usbDriver, usbDev, bitmap);
//            // 分割线
//            usbDriver.write(PrintCmd.PrintString("----------------------------------------------\n\n", 0), usbDev);
//            // 小票标题
//            usbDriver.write(PrintCmd.SetBold(0), usbDev); // 0不加粗 1加粗
//            usbDriver.write(PrintCmd.SetAlignment(1), usbDev); // 字符对其：0左 1中 2右
//            usbDriver.write(PrintCmd.SetSizetext(1, 1), usbDev); // 放大高度 放大宽度（0-8）
//            usbDriver.write(PrintCmd.PrintString(store.getShopName() + "\n", 0), usbDev); // 0换行 1不换行
//            usbDriver.write(PrintCmd.SetAlignment(0), usbDev);
//            usbDriver.write(PrintCmd.SetSizetext(0, 0), usbDev);
//            // 商店信息
//            usbDriver.write(PrintCmd.PrintString(
//                    resources.getString(R.string.shop_num) + store.getShopId(), 0), usbDev);
//            usbDriver.write(PrintCmd.PrintString(
//                    resources.getString(R.string.shop_note_num) + PayResponse.getInstance().getOrderId(), 0), usbDev);
//            usbDriver.write(PrintCmd.PrintString(
//                    resources.getString(R.string.shop_cashier_num) + store.getDeviceNum(), 0), usbDev);
//            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
//            String time = dateFormat.format(new Date());
//            usbDriver.write(PrintCmd.PrintString(
//                    resources.getString(R.string.shop_receipt_date) + time.substring(0, 10), 0), usbDev);
//            usbDriver.write(PrintCmd.PrintString(
//                    resources.getString(R.string.shop_print_time) + time, 0), usbDev);
//            // 打印购物清单
//            printMSTable(resources, usbDev, usbDriver);
//            // 打印票尾
//            usbDriver.write(PrintCmd.PrintString(
//                    resources.getString(R.string.shop_goods_number)
//                            + "                                "
//                            + TradeInfo.getInstance().getTotalNumber(), 0), usbDev);
//            usbDriver.write(PrintCmd.PrintString(
//                    resources.getString(R.string.shop_goods_total_price)
//                            + "                                "
//                            + TradeInfo.getInstance().getTotalPrice(), 0), usbDev);
//            usbDriver.write(PrintCmd.PrintString(
//                    resources.getString(R.string.shop_discont)
//                            + "                                "
//                            + TradeInfo.getInstance().getDiscount(), 0), usbDev);
//            usbDriver.write(PrintCmd.PrintString(
//                    resources.getString(R.string.shop_payment)
//                            + "                                "
//                            + TradeInfo.getInstance().getTotalPrice(), 0), usbDev);
//            usbDriver.write(PrintCmd.PrintString(
//                    "==============================================", 0), usbDev);
//            usbDriver.write(PrintCmd.SetAlignment(1), usbDev); // 字符对其：0左 1中 2右
//            usbDriver.write(PrintCmd.SetSizetext(0, 0), usbDev); // 放大高度 放大宽度（0-8）
//            usbDriver.write(PrintCmd.PrintString(
//                    resources.getString(R.string.shop_thanks) + "\n\n\n", 0), usbDev); // 0换行 1不换行
//            usbDriver.write(PrintCmd.SetAlignment(0), usbDev);
//            usbDriver.write(PrintCmd.SetSizetext(0, 0), usbDev);
//
//            // 走纸换行、切纸、清理缓存
//            setFeedCut(1, usbDev, usbDriver); // 0全切 1半切
//        } catch (Exception e) {
//            LogFileUtil.writeLog(e.getMessage());
//        }
//    }
//
//    private static void printMSTable(Resources resources, UsbDevice usbDev, UsbDriver usbDriver) {
//        String column = resources.getString(R.string.note_title);
//        Table table = null;
//        table = new Table(column, ";", new int[]{18, 10, 10, 12});
//        ArrayList<GoodsInfo> goodsList = TradeInfo.getInstance().getGoodsList();
//        for (int i = 0; i < goodsList.size(); i++) {
//            GoodsInfo goodBean = goodsList.get(i);
//            String totalPrice = String.format(Locale.getDefault(), "%.2f", goodBean.getTotal());
//            table.addRow(goodBean.getName() + ";" + goodBean.getPrice() + ";" + goodBean.getQty() + ";" + totalPrice);
//        }
//        usbDriver.write(PrintCmd.PrintString(table.getTableText(), 0), usbDev); // 0换行 1不换行
//    }
//
//    private static void printMSWD(UsbDriver usbDriver, UsbDevice usbDev, Bitmap bitmap) {
//        // 上部文字
//        usbDriver.write(PrintCmd.SetBold(0), usbDev); // 0不加粗 1加粗
//        usbDriver.write(PrintCmd.SetAlignment(1), usbDev); // 字符对其：0左 1中 2右
//        usbDriver.write(PrintCmd.SetSizetext(1, 1), usbDev); // 放大高度 放大宽度（0-8）
//        usbDriver.write(PrintCmd.PrintString(PayResponse.getInstance().getDeliveryMoney() + "\n", 0), usbDev); // 0换行 1不换行
//        usbDriver.write(PrintCmd.SetSizetext(0, 0), usbDev);
//        usbDriver.write(PrintCmd.PrintString(PayResponse.getInstance().getUpImageMessage() + "\n", 0), usbDev); // 0换行 1不换行
//        usbDriver.write(PrintCmd.SetLeftmargin(140)); // 设置左边界 0-576
//        // 打印二维码
//        int[] data = getPixelsByBitmap(bitmap);
//        usbDriver.write(PrintCmd.PrintDiskImagefile(data, bitmap.getWidth(), bitmap.getHeight()));
////        usbDriver.write(PrintCmd.PrintQrcode(
////                TradeInfo.getInstance().getUrlAddress(), 14, 8, 1), usbDev);
//        usbDriver.write(PrintCmd.SetLeftmargin(0)); // 设置左边界 0-576
//        // 下部文字
//        usbDriver.write(PrintCmd.PrintString(
//                "\n\n" + PayResponse.getInstance().getDownImageMessage() + "\n\n", 0), usbDev); // 0换行 1不换行
//    }

    /**
     * jpg png bmp 彩色图片转换Bitmap数据为int[]数组
     *
     * @param bm
     * @return int[]
     */
    public static int[] getPixelsByBitmap(Bitmap bm) {
        int width, heigh;
        width = bm.getWidth();
        heigh = bm.getHeight();
        int iDataLen = width * heigh;
        int[] pixels = new int[iDataLen];
        bm.getPixels(pixels, 0, width, 0, 0, width, heigh);
        return pixels;
    }

    // 检测打印机状态
    private static int getPrinterStatus(UsbDevice usbDev, UsbDriver usbDriver) {
        int iRet = -1;

        byte[] bRead1 = new byte[1];
        byte[] bWrite1 = PrintCmd.GetStatus1();
        if (usbDriver.read(bRead1, bWrite1, usbDev) > 0) {
            iRet = PrintCmd.CheckStatus1(bRead1[0]);
        }

        if (iRet != 0)
            return iRet;

        byte[] bRead2 = new byte[1];
        byte[] bWrite2 = PrintCmd.GetStatus2();
        if (usbDriver.read(bRead2, bWrite2, usbDev) > 0) {
            iRet = PrintCmd.CheckStatus2(bRead2[0]);
        }

        if (iRet != 0)
            return iRet;

        byte[] bRead3 = new byte[1];
        byte[] bWrite3 = PrintCmd.GetStatus3();
        if (usbDriver.read(bRead3, bWrite3, usbDev) > 0) {
            iRet = PrintCmd.CheckStatus3(bRead3[0]);
        }

        if (iRet != 0)
            return iRet;

        byte[] bRead4 = new byte[1];
        byte[] bWrite4 = PrintCmd.GetStatus4();
        if (usbDriver.read(bRead4, bWrite4, usbDev) > 0) {
            iRet = PrintCmd.CheckStatus4(bRead4[0]);
        }


        return iRet;
    }

    private static String convertPrintStatus(int iStatus) {
        //0 打印机正常 、1 打印机未连接或未上电、2 打印机和调用库不匹配
        //3  、4  、5  、6 黑标错误 、7 纸尽 、8 纸将尽
        switch (iStatus) {
            case 0:
                return "";
            case 8:
                return "";
            case 3:
                return "打印头打开";
            case 4:
                return "切刀未复位";
            case 5:
                return "打印头过热";
            case 6:
                return "黑标错误";
            case 7:
                return "打印纸耗尽";
            case 1:
                return "打印机未连接或未上电";
            case 2:
                return "打印机和调用库不匹配";
            default:
                return "错误码:"+iStatus;
        }
    }


    private static int checkStatus(int iStatus) {
        int iRet = -1;
        //0 打印机正常 、1 打印机未连接或未上电、2 打印机和调用库不匹配
        //3 打印头打开 、4 切刀未复位 、5 打印头过热 、6 黑标错误 、7 纸尽 、8 纸将尽
        switch (iStatus) {
            case 0:
                iRet = 0;
                break;
            case 8:
                iRet = 0;
                break;
            case 3:
                break;
            case 4:
                break;
            case 5:
                break;
            case 6:
                break;
            case 7:
                break;
            case 1:
                break;
            default:
                break;
        }
        return iRet;
    }

    // 走纸换行、切纸、清理缓存
    private static void setFeedCut(int iMode, UsbDevice usbDev, UsbDriver usbDriver) {
        usbDriver.write(PrintCmd.PrintFeedline(10), usbDev);      // 走纸换行
        usbDriver.write(PrintCmd.PrintCutpaper(iMode), usbDev);  // 切纸类型
    }
    // --------------------- 美松 lyq end ---------------------

    public static boolean isUsbPrinter(UsbDevice device) {
        int vendorId = device.getVendorId();
        int productId = device.getProductId();
        if ((1305 == vendorId && 8211 == productId)) {
            // 美松打印机
            return true;
        }
        return false;
    }

}
